package org.fuys.etp.core;

import javafx.util.Pair;
import org.fuys.etp.core.metrics.EtpMetricsHandlerChain;
import org.fuys.etp.core.model.res.TpStatusResult;
import org.fuys.etp.core.model.type.EtpTypeEnum;
import org.fuys.etp.core.model.vo.TpStatusVO;
import org.fuys.etp.core.pool.EtpThreadPoolExecutor;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @projectName: fuys-etp-final
 * @package: org.fuys.etp.core
 * @className: EtpCollector
 * @author: WangJing
 * @description: 动态线程池指标收集器
 * @date: 2025/2/18 21:29
 * @version: 1.0
 */
@Component
public class EtpCollector {

    @Resource
    private EtpManager etpManager;

    @Resource(name = "defaultCommonMetricsHandlerChain")
    private EtpMetricsHandlerChain commonHandlerChain;


    Map<Pair<String,String>,TpStatusResult> metrics = new ConcurrentHashMap<>();

    public void updateForMetrics(TpStatusResult report) {
        metrics.put(new Pair<>(report.getPoolType(),report.getPoolName()),report);
    }

    public TpStatusResult getPoolMetrics(String poolType,String poolName){
        final Pair<String, String> key = new Pair<>(poolType, poolName);
        if(!metrics.containsKey(key)){
            this.newPoolMetrics(poolType,poolName);
        }
        return metrics.get(key);
    }

    public TpStatusResult newPoolMetrics(String poolType,String poolName){
        final Pair<String, String> key = new Pair<>(poolType, poolName);
        ThreadPoolExecutor executor = etpManager.getExecutor(key);
        if(executor == null){
            return TpStatusResult.builder().poolName("不存在的线程池").poolType("UNKNOWN").build();
        }
        if(EtpTypeEnum.COMMON_THREAD_POOL_EXECUTOR.type().equals(poolType)){
            final TpStatusVO tpStatusVO = commonHandlerChain.collectStatus(executor);
            metrics.put(key,TpStatusResult.builder().tpStatusVO(tpStatusVO)
                    .takeover(false).poolName(poolName).poolType(poolType).build());
        }else if (EtpTypeEnum.ADAPTIVE_THREAD_POOLS_EXECUTOR.type().equals(poolType)
                || EtpTypeEnum.STAGE_SWITCH_THREAD_POOL_EXECUTOR.type().equals(poolType)){
            EtpThreadPoolExecutor etp = (EtpThreadPoolExecutor) executor;
            metrics.put(key,etp.statusExplore());
        }
        return metrics.get(key);
    }

    public List<TpStatusResult> getAllPoolMetrics() {
        return new ArrayList<>(metrics.values());
    }
}
